package com.cskaoyan.wordmemorize.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cskaoyan.wordmemorize.common.aspect.operate.OperateLog;
import com.cskaoyan.wordmemorize.common.aspect.operate.OperateLogConstant;
import com.cskaoyan.wordmemorize.common.constant.ResultCodeEnum;
import com.cskaoyan.wordmemorize.common.exception.BusinessException;
import com.cskaoyan.wordmemorize.converter.GoodsConverter;
import com.cskaoyan.wordmemorize.dao.entity.GoodsDO;
import com.cskaoyan.wordmemorize.dao.mapper.GoodsMapper;
import com.cskaoyan.wordmemorize.dto.admin.DeleteGoodsOperateDTO;
import com.cskaoyan.wordmemorize.dto.admin.GoodsDTO;
import com.cskaoyan.wordmemorize.dto.admin.PageDTO;
import com.cskaoyan.wordmemorize.request.BatchDeleteCommand;
import com.cskaoyan.wordmemorize.request.GoodsCommand;
import com.cskaoyan.wordmemorize.request.GoodsPageRequest;
import com.cskaoyan.wordmemorize.service.GoodsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

@Service
public class GoodsServiceImpl implements GoodsService {

    @Autowired
    GoodsMapper goodsMapper;

    @Autowired
    GoodsConverter goodsConverter;

    @Override
    public PageDTO<GoodsDTO> getGoodsPage(GoodsPageRequest request) {
        if (request.getPageNum() == null) {
            LambdaQueryWrapper<GoodsDO> goodsWrapper = new LambdaQueryWrapper<>();
            goodsWrapper.in(request.getTypes() != null, GoodsDO::getType, request.getTypes())
                    .like(request.getKeyword() != null, GoodsDO::getName, request.getKeyword());
            List<GoodsDO> goodsDOS = goodsMapper.selectList(goodsWrapper);
            return goodsConverter.goodsPage2PageDTO(goodsDOS, (long)goodsDOS.size());
        }
        Page<GoodsDO> pageParam = new Page<>(request.getPageNum(), request.getCount());
        LambdaQueryWrapper<GoodsDO> goodsWrapper = new LambdaQueryWrapper<>();
        goodsWrapper.in(request.getTypes() != null, GoodsDO::getType, request.getTypes())
                .like(request.getKeyword() != null, GoodsDO::getName, request.getKeyword());
        Page<GoodsDO> goodsDOPage = goodsMapper.selectPage(pageParam, goodsWrapper);
        return goodsConverter.goodsPage2PageDTO(goodsDOPage.getRecords(), goodsDOPage.getTotal());
    }

    @Override
    @OperateLog(dateType = "商品", operateType = OperateLogConstant.OPERATE_ADD)
    public void addGoods(GoodsCommand command) {
        LambdaQueryWrapper<GoodsDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(GoodsDO::getName, command.getName());
        GoodsDO goodsDO = goodsMapper.selectOne(queryWrapper);
        if (goodsDO != null) {
            throw new RuntimeException("商品已存在");
        }
        GoodsDO good = goodsConverter.command2GoodsDO(command);
        goodsMapper.insert(good);
    }

    @Override
    @OperateLog(dateType = "商品", operateType = OperateLogConstant.OPERATE_UPDATE)
    public void updateGoods(GoodsCommand command) {
        GoodsDO goodsDO = goodsConverter.command2GoodsDO(command);
        goodsDO.setId(Long.valueOf(command.getId()));
        goodsMapper.updateById(goodsDO);
    }

    @Override
    @OperateLog(dateType = "商品", operateType = OperateLogConstant.OPERATE_SINGLE_DELETE)
    public DeleteGoodsOperateDTO deleteGoods(Long goodsId) {
        GoodsDO goodsDO = goodsMapper.selectById(goodsId);
        if (goodsDO == null) {
            throw new BusinessException(ResultCodeEnum.GOODS_NOT_EXIST);
        }
        goodsMapper.deleteById(goodsDO);
        return goodsConverter.goodsDO2DeleteGoodsDTO(goodsDO);
    }

    @Override
    @OperateLog(dateType = "商品", operateType = OperateLogConstant.OPERATE_BATCH_DELETE)
    public List<DeleteGoodsOperateDTO> deleteGoodsSelected(BatchDeleteCommand command) {
        List<Long> ids = command.getIds().stream()
                .map(Long::parseLong)
                .collect(Collectors.toList());
        goodsMapper.deleteByIds(ids);
        List<GoodsDO> goodsDOS = goodsMapper.selectByIds(ids);
        List<DeleteGoodsOperateDTO> deleteGoodsOperateDTOS = goodsConverter.goodsDOs2DeleteGoodsDTOs(goodsDOS);
        return deleteGoodsOperateDTOS;
    }

    @Override
    @OperateLog(dateType = "商品", operateType = OperateLogConstant.OPERATE_UPDATE_STATUS)
    public void updateGoodsStatus(Long goodsId, Integer status) {
        GoodsDO goodsDO = goodsMapper.selectById(goodsId);
        if (goodsDO == null) {
            throw new BusinessException(ResultCodeEnum.GOODS_NOT_EXIST);
        }
        goodsDO.setStatus(status);
        goodsMapper.updateById(goodsDO);
    }
}
